﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Hopscotch.Test.Presentation;
using Moq;
using NUnit.Framework;

namespace Hopscotch.Presentation.Common.Test
{

    [TestFixture]
    public class ViewModelBaseTest
    {
        private TestViewModel testViewModel;

        [SetUp]
        public void Setup()
        {
            testViewModel = new TestViewModel();
        }

        [Test]
        public void TestErrorsAreAddedInOrder()
        {
            testViewModel.AddInfo("Property", "Info 1");
            testViewModel.AddError("Property", "Error 1");
            testViewModel.AddWarning("Property", "Warning 1");			
            testViewModel.AddInfo("Property", "Info 2");
            testViewModel.AddWarning("Property", "Warning 2");
            testViewModel.AddError("Property", "Error 2");

            var errors = testViewModel.GetErrors("Property");
            List<DataErrorInfo> list = errors.Cast<DataErrorInfo>().ToList<DataErrorInfo>();
            list[0].Description.Should().Be("Error 1");
            list[1].Description.Should().Be("Error 2");
            list[2].Description.Should().Be("Warning 1");
            list[3].Description.Should().Be("Warning 2");
            list[4].Description.Should().Be("Info 1");
            list[5].Description.Should().Be("Info 2");
        }

        [Test]
        public void TestAddingErrorsInReverseOrderRetrievesInSortedOrder()
        {
            testViewModel.AddInfo("Property", "Info");
            testViewModel.AddWarning("Property", "Warning");
            testViewModel.AddError("Property", "Error");

            var errors = testViewModel.GetErrors("Property");
            List<DataErrorInfo> list = errors.Cast<DataErrorInfo>().ToList<DataErrorInfo>();
            list[0].ErrorType.Should().Be(ErrorType.Error);
            list[1].ErrorType.Should().Be(ErrorType.Warning);
            list[2].ErrorType.Should().Be(ErrorType.Info);
        }

        [Test]
        public void TestValidateRaisesErrorsChanged()
        {
            bool called = false;

            testViewModel.ErrorsChanged += (s, e) => { called = true; };
            testViewModel.AddError("Property", "Error");

            testViewModel.Validate();
            called.Should().BeTrue();
        }

        [Test]
        public void TestValidateClearsErrorCollection()
        {
            testViewModel.AddError("Property", "Error");

            testViewModel.Validate();
            testViewModel.OnValidateCalled.Should().BeTrue();

            var errors = testViewModel.GetErrors("Property");
            errors.Should().BeNullOrEmpty();
        }
    }
}
